package com.btb.adapter.utils;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Objects;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.datatypes.Function;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.EthEstimateGas;
import org.web3j.protocol.core.methods.response.EthGasPrice;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Web3jUtils {
	public static String fmt(String hexVal) {
		if(Objects.isNull(hexVal)) {
			return StringUtils.EMPTY;
		}
		BigInteger decodeQuantity = Numeric.decodeQuantity(hexVal);
		String amount = Convert.fromWei(decodeQuantity.toString(), Convert.Unit.ETHER).stripTrailingZeros()
				.toPlainString();
		return amount;
	}

	public static String fmt(BigInteger hexVal) {
		if(Objects.isNull(hexVal)) {
			return StringUtils.EMPTY;
		}
		String amount = Convert.fromWei(hexVal.toString(), Convert.Unit.ETHER).stripTrailingZeros().toPlainString();
		return amount;
	}

	public static TransactionReceipt query(Web3j web3j, String transactionHash) {
		Request<?, EthGetTransactionReceipt> ethGetTransactionReceipt = web3j.ethGetTransactionReceipt(transactionHash);
		try {
			EthGetTransactionReceipt send = ethGetTransactionReceipt.send();
			return Optional.ofNullable(send).map(EthGetTransactionReceipt::getResult).orElse(null);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * GasPrice
	 *
	 * @param web3j
	 * @return
	 */
	public static BigInteger gasPrice(Web3j web3j) {
		EthGasPrice ethGasPrice = null;
		try {
			ethGasPrice = web3j.ethGasPrice().send();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return Optional.ofNullable(ethGasPrice).map(EthGasPrice::getGasPrice).orElse(null);
	}
	public static BigInteger gasLimit(Web3j web3j, String from, String to, Function function) {
		Transaction transaction = Transaction.createEthCallTransaction(from, to, FunctionEncoder.encode(function));
		try {
			EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(transaction).send();
			if (ethEstimateGas.hasError()) {
				throw new RuntimeException(ethEstimateGas.getError().getMessage());
			}
			return ethEstimateGas.getAmountUsed();
		} catch (IOException e) {
			throw new RuntimeException("net error");
		}
	}
	public static String queryTimestamp(Web3j web3j, BigInteger blockNumber) {
		String timestamp = "";
		try {
			EthBlock ethBlock = web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(blockNumber), false).send();
			timestamp = String.valueOf(ethBlock.getBlock().getTimestamp());
		} catch (Exception e) {
			log.error("Block timestamp get failure,block number is {}", blockNumber);
			log.error("Block timestamp get failure,{}", e);
		}
		return timestamp;
	}
}
